package dbexel.presentation.aat;

import static org.junit.Assert.*;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.ConfirmHandler;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebAssert;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTable;

import dbexel.model.dao.JPATestTools;
import dbexel.model.dao.WorkSheetDao;
import dbexel.model.dao.WorkSheetDaoImpl;
import dbexel.model.mapping.AttributeValue;
import dbexel.model.mapping.WorkSheet;
import dbexel.model.mapping.WorkSheet_Attribute;
import dbexel.model.mapping.WorkSheet_Entry;
import dbexel.system.tools.DBExelTestTools;
import dbexel.system.tools.FileUtils;

public class WorkSheetEntryAAT {
	private static WorkSheetDao wsDao = new WorkSheetDaoImpl();
	private WebClient webClient;

	@BeforeClass
	public static void cleanSystem() {
		JPATestTools.cleanAllData();
	}

	@Before
	public void initSystem() {

		webClient = new WebClient();
		webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
		webClient.setJavaScriptEnabled(true);
		webClient.getCookieManager().setCookiesEnabled(true);
	}

	@After
	public void cleanWindows() {
		JPATestTools.cleanAllData();
		webClient.closeAllWindows();
	}

	// In this test we add a new entry to the worksheet
	@Test
	public void testAddAnEntry() throws FailingHttpStatusCodeException,
			MalformedURLException, IOException {

		WorkSheet l_workSheet = fetchTestWorkSheet("testAddAnEntry");

		wsDao.createWorkSheet(l_workSheet);

		HtmlPage l_currentPage = (HtmlPage) webClient.getPage(new URL(FileUtils
				.fetchProperty("dbexel.testsite") + "/DBEXEL/"));

		// Enter New Worksheet
		l_currentPage = l_currentPage.getAnchorByText(l_workSheet.getWs_Name())
				.click();

		// Validate Table
		// We should have 3 lines in the table
		HtmlTable l_currentTable = DBExelTestTools
				.getTableByOrder(l_currentPage);
		assertEquals(3, l_currentTable.getRowCount());

		WebAssert.assertLinkPresentWithText(l_currentPage, "Add an Entry");

		// Go to the Add entry page
		l_currentPage = l_currentPage.getAnchorByText("Add an Entry").click();

		// Validate Table
		l_currentTable = DBExelTestTools.getTableByOrder(l_currentPage, 1);

		// We should have 4 lines in the table
		assertEquals(4, l_currentTable.getRowCount());

		// We should have 5 columns
		assertEquals(5, l_currentTable.getRow(0).getCells().size());

		HtmlForm l_currentForm = l_currentPage
				.getFormByName("AddNewEntryToWorkSheet");

		List<HtmlInput> l_inputFields = DBExelTestTools
				.fetchVisibleInputFields(l_currentForm);

		assertEquals(5, l_inputFields.size());

		for (int i = 0; i < 5; i++) {
			l_inputFields.get(i).setValueAttribute(Integer.toString(10 + i));
		}

		// Submit for to go back to the previous page
		l_currentPage = DBExelTestTools.getSubmitButton(l_currentForm).click();

		// Check that the given values are present
		// Validate Table
		l_currentTable = DBExelTestTools.getTableByOrder(l_currentPage);

		// We should now have 5 lines in the table
		assertEquals(4, l_currentTable.getRowCount());
	}

	// In this test we edit an entry in the worksheet
	@Test
	public void testEditAnEntry() throws FailingHttpStatusCodeException,
			MalformedURLException, IOException {

		WorkSheet l_workSheet = fetchTestWorkSheet("testEditAnEntry");

		wsDao.createWorkSheet(l_workSheet);

		// Get first page
		HtmlPage l_currentPage = (HtmlPage) webClient.getPage(new URL(FileUtils
				.fetchProperty("dbexel.testsite") + "/DBEXEL/"));

		// Enter New Worksheet
		l_currentPage = l_currentPage.getAnchorByText(l_workSheet.getWs_Name())
				.click();

		HtmlTable l_currentTable = DBExelTestTools
				.getTableByOrder(l_currentPage);

		WebAssert.assertLinkPresentWithText(l_currentPage, "Edit");

		String l_oldValue = "Attr3 valX";

		// Test Before Edit
		assertEquals(l_oldValue, l_currentTable.getRow(2).getCell(2)
				.getTextContent());

		HtmlAnchor l_currentAnchor = DBExelTestTools.getAnchorById(
				l_currentPage, "editLink_2");

		// Go to the Edit entry page
		l_currentPage = l_currentAnchor.click();

		WebAssert.assertTitleEquals(l_currentPage, "Update Worksheet Entry");

		HtmlForm l_currentForm = l_currentPage
				.getFormByName("EditWorkSheetEntry");

		l_currentTable = DBExelTestTools
				.getTableByOrder(l_currentPage);
		
		assertEquals(5, l_currentTable.getRow(0).getCells().size());
		
		assertEquals(
				5,
				DBExelTestTools.getInputsByNameStart(l_currentForm,
						"newAttributeValues[").size());

		HtmlInput l_input = DBExelTestTools.getInputsByNameStart(l_currentForm,
				"newAttributeValues[").get(2);

		assertEquals(l_oldValue, l_input.getValueAttribute());

		String l_newValue = "Attr3X valX3";
		l_input.setValueAttribute(l_newValue);

		// Press Submit
		l_currentPage = DBExelTestTools.getSubmitButton(l_currentForm).click();

		l_currentTable = DBExelTestTools.getTableByOrder(l_currentPage);

		assertEquals(l_newValue, l_currentTable.getRow(2).getCell(2)
				.getTextContent());
	}

	// In this test we delete an entry in the worksheet
	@Test
	public void testDeleteAnEntry() throws FailingHttpStatusCodeException,
			MalformedURLException, IOException {
		WorkSheet l_workSheet = fetchTestWorkSheet("testEditAnEntry");

		wsDao.createWorkSheet(l_workSheet);

		// Get first page
		HtmlPage l_currentPage = (HtmlPage) webClient.getPage(new URL(FileUtils
				.fetchProperty("dbexel.testsite") + "/DBEXEL/"));

		// Enter New Worksheet
		l_currentPage = l_currentPage.getAnchorByText(l_workSheet.getWs_Name())
				.click();

		HtmlTable l_currentTable = DBExelTestTools
				.getTableByOrder(l_currentPage);

		WebAssert.assertLinkPresentWithText(l_currentPage, "Delete");
		assertEquals(3, l_currentTable.getRowCount());
		String l_oldValue = "Attr3 valX";

		// Test Before Edit
		assertEquals(l_oldValue, l_currentTable.getRow(2).getCell(2)
				.getTextContent());

		// Start deleting page
		webClient.setConfirmHandler(new ConfirmHandler() {
			public boolean handleConfirm(Page page, String message) {
				return false;
			}
		});

		boolean l_isNotConfirmed = webClient.getConfirmHandler().handleConfirm(
				l_currentPage, "Delete this work sheet?");

		assertFalse("Confirm window has not been invoked", l_isNotConfirmed);

		// Press Delete
		l_currentPage = DBExelTestTools.getAnchorById(l_currentPage,
				"deleteLink_2").click();

		// Now we should be back in the worksheet details page
		assertEquals("Work Sheet " + l_workSheet.getWs_Name() + " Details",
				l_currentPage.getTitleText());

		l_currentTable = DBExelTestTools.getTableByOrder(l_currentPage);

		assertEquals(3, l_currentTable.getRowCount());

		// Start deleting page
		webClient.setConfirmHandler(new ConfirmHandler() {
			public boolean handleConfirm(Page page, String message) {
				return true;
			}
		});

		l_isNotConfirmed = webClient.getConfirmHandler().handleConfirm(
				l_currentPage, "Delete this Entry?");

		assertTrue("Confirm window has not been invoked", l_isNotConfirmed);

		// Press Delete
		l_currentPage = DBExelTestTools.getAnchorById(l_currentPage,
				"deleteLink_2").click();

		// Now we should be back in the worksheet details page
		assertEquals("Work Sheet " + l_workSheet.getWs_Name() + " Details",
				l_currentPage.getTitleText());

		l_currentTable = DBExelTestTools.getTableByOrder(l_currentPage);

		assertEquals(2, l_currentTable.getRowCount());
		
		//Let's see if the attributes are still there
		l_currentTable = DBExelTestTools.getTableByOrder(l_currentPage);
		
		assertEquals("Column 3", l_currentTable.getRow(0).getCell(0).getTextContent());
		assertEquals("Column 7", l_currentTable.getRow(0).getCell(2).getTextContent());
		assertEquals("Column 13", l_currentTable.getRow(0).getCell(4).getTextContent());
	}
	

	//
	private WorkSheet fetchTestWorkSheet(String in_string) {
		WorkSheet l_workSheet = new WorkSheet(in_string);
		// l_workSheet.setWs_Id(new Long(17));

		WorkSheet_Attribute l_wsAttr1 = new WorkSheet_Attribute("Column 3");
		// l_wsAttr1.setAttrId(new Long(8));
		WorkSheet_Attribute l_wsAttr2 = new WorkSheet_Attribute("Column 5");
		// l_wsAttr2.setAttrId(new Long(9));
		WorkSheet_Attribute l_wsAttr3 = new WorkSheet_Attribute("Column 7");
		// l_wsAttr3.setAttrId(new Long(23));
		WorkSheet_Attribute l_wsAttr4 = new WorkSheet_Attribute("Column 11");
		// l_wsAttr4.setAttrId(new Long(27));
		WorkSheet_Attribute l_wsAttr5 = new WorkSheet_Attribute("Column 13");
		// l_wsAttr5.setAttrId(new Long(31));

		// Add attributes
		l_workSheet.attachAttribute(l_wsAttr1);
		l_workSheet.attachAttribute(l_wsAttr2);
		l_workSheet.attachAttribute(l_wsAttr3);
		l_workSheet.attachAttribute(l_wsAttr4);
		l_workSheet.attachAttribute(l_wsAttr5);

		// Add Antries
		l_workSheet.addEntry(new WorkSheet_Entry());
		l_workSheet.addEntry(new WorkSheet_Entry());

		// l_workSheet.getEntries().get(0).setEntryId(new Long(37));
		// l_workSheet.getEntries().get(1).setEntryId(new Long(41));

		// Fill the entries
		l_workSheet
				.getEntries()
				.get(0)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr1, "Attr1 valA"));
		l_workSheet
				.getEntries()
				.get(0)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr2, "Attr2 valB"));
		l_workSheet
				.getEntries()
				.get(0)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr3, "Attr3 valC"));
		l_workSheet
				.getEntries()
				.get(0)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr4, "Attr4 valD"));
		l_workSheet
				.getEntries()
				.get(0)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr5, "Attr5 valE"));

		l_workSheet
				.getEntries()
				.get(1)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr1, "Attr1 valZ"));
		l_workSheet
				.getEntries()
				.get(1)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr2, "Attr2 valY"));
		l_workSheet
				.getEntries()
				.get(1)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr3, "Attr3 valX"));
		l_workSheet
				.getEntries()
				.get(1)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr4, "Attr4 valW"));
		l_workSheet
				.getEntries()
				.get(1)
				.attachAttributeValue(
						new AttributeValue(l_wsAttr5, "Attr5 valV"));

		return l_workSheet;
	}
}
